package com.study.exchange.direct;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.study.constant.Constant;
import com.study.entity.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.amqp.utils.SerializationUtils;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

@Slf4j
@Component
public class ConsumerMessageListener {
    @RabbitHandler
    @RabbitListener(queues = Constant.DirectConstant.INFO_LOG_QUEUE, concurrency = "2", ackMode = "MANUAL")//监听的队列名称 TestDirectQueue
    public void infoLogConsumerProcess(Map<String, String> msg, Message message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        try {
            Object body = SerializationUtils.deserialize(message.getBody());
            log.info("infoLogConsumerProcess消费者收到消息:msg={},message={},deliveryTag={} ", JSON.toJSON(msg), JSON.toJSON(body), deliveryTag);

            // https://blog.csdn.net/qq_35237533/article/details/121468715

            // https://blog.csdn.net/QingXu1234/article/details/123954806
            channel.basicAck(deliveryTag, true);
        } catch (IOException e1) {
            try {
                channel.basicAck(deliveryTag, false);
            } catch (IOException e2) {
                log.error(e2.getMessage(), e2);
            }
        }
    }

    @RabbitHandler
    @RabbitListener(queues = Constant.DirectConstant.ERROR_LOG_QUEUE, concurrency = "1", ackMode = "MANUAL")//监听的队列名称 TestDirectQueue
    public void errorLogConsumerProcess(Log logEntity, Message message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        try {
            // 除了可以在方法中指定一个对象（用什么对象接收，取决于你往队列中塞的消息是啥，rabbitMQ会帮我们自动反序列化）接收参数，还可以通过message.getBody()获取消息
            Object body = SerializationUtils.deserialize(message.getBody());
            log.info("errorLogConsumerProcess消费者收到消息:user={},message={},deliveryTag={} ", logEntity.toString(), body.toString(), deliveryTag);
            channel.basicAck(deliveryTag, true);
        } catch (IOException e1) {
            try {
                channel.basicAck(deliveryTag, false);
            } catch (IOException e2) {
                ConsumerMessageListener.log.error(e2.getMessage(), e2);
            }
        }
    }
}
